using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using SeataNet.Core;
using SeataNet.Core.Configuration;
using SeataNet.PerformanceTests;

namespace SeataNet.PerformanceTests
{
    /// <summary>
    /// 性能测试程序入口
    /// </summary>
    public class Program
    {
        /// <summary>
        /// 程序入口点
        /// </summary>
        /// <param name="args">命令行参数</param>
        /// <returns>程序退出码</returns>
        public static async Task<int> Main(string[] args)
        {
            try
            {
                Console.WriteLine("SeataNet 性能测试开始...");
                Console.WriteLine("========================================");

                // 配置服务容器
                var services = new ServiceCollection();
                ConfigureServices(services);

                // 构建服务提供者
                using var serviceProvider = services.BuildServiceProvider();

                // 初始化SeataNet
                var seataConfiguration = serviceProvider.GetRequiredService<SeataConfiguration>();
                await InitializeSeataAsync(seataConfiguration);

                // 执行性能测试
                await RunPerformanceTestsAsync(serviceProvider);

                Console.WriteLine("========================================");
                Console.WriteLine("SeataNet 性能测试完成");
                return 0;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"性能测试执行失败: {ex.Message}");
                Console.WriteLine($"详细信息: {ex}");
                return 1;
            }
        }

        /// <summary>
        /// 配置服务
        /// </summary>
        /// <param name="services">服务集合</param>
        private static void ConfigureServices(IServiceCollection services)
        {
            // 添加配置
            var configuration = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                .AddEnvironmentVariables()
                .Build();

            services.AddSingleton<IConfiguration>(configuration);

            // 添加日志
            services.AddLogging(builder =>
            {
                builder.AddConsole();
                builder.AddDebug();
                builder.SetMinimumLevel(LogLevel.Information);
            });

            // 添加SeataNet核心服务
            services.AddSeataNet(config =>
            {
                config.ApplicationId = "performance-test";
                config.TxServiceGroup = "default";
            });

            // 添加性能测试服务
            services.AddSingleton<PerformanceTestBase>();
            services.AddSingleton<AtModePerformanceTest>();
            services.AddSingleton<TccModePerformanceTest>();
            services.AddSingleton<SagaModePerformanceTest>();

            // 添加模拟服务
            services.AddTransient<AtModePerformanceTest.MockUserService>();
            services.AddTransient<AtModePerformanceTest.MockOrderService>();
            services.AddTransient<AtModePerformanceTest.MockInventoryService>();
            services.AddTransient<AtModePerformanceTest.MockPaymentService>();
            services.AddTransient<AtModePerformanceTest.MockLogisticsService>();

            services.AddTransient<TccModePerformanceTest.MockPaymentService>();
            services.AddTransient<TccModePerformanceTest.MockInventoryService>();
            services.AddTransient<TccModePerformanceTest.MockOrderService>();
            services.AddTransient<TccModePerformanceTest.MockLogisticsService>();

            services.AddTransient<SagaModePerformanceTest.MockUserService>();
            services.AddTransient<SagaModePerformanceTest.MockPaymentService>();
            services.AddTransient<SagaModePerformanceTest.MockInventoryService>();
            services.AddTransient<SagaModePerformanceTest.MockOrderService>();
            services.AddTransient<SagaModePerformanceTest.MockLogisticsService>();
            services.AddTransient<SagaModePerformanceTest.MockNotificationService>();
        }

        /// <summary>
        /// 初始化SeataNet
        /// </summary>
        /// <param name="configuration">SeataNet配置</param>
        private static async Task InitializeSeataAsync(SeataConfiguration configuration)
        {
            Console.WriteLine("正在初始化SeataNet...");

            // 这里可以添加SeataNet的初始化逻辑
            // 例如连接TC服务器、注册服务等

            Console.WriteLine("SeataNet初始化完成");
        }

        /// <summary>
        /// 运行性能测试
        /// </summary>
        /// <param name="serviceProvider">服务提供者</param>
        private static async Task RunPerformanceTestsAsync(IServiceProvider serviceProvider)
        {
            var logger = serviceProvider.GetRequiredService<ILogger<Program>>();
            var atModeTest = serviceProvider.GetRequiredService<AtModePerformanceTest>();
            var tccModeTest = serviceProvider.GetRequiredService<TccModePerformanceTest>();
            var sagaModeTest = serviceProvider.GetRequiredService<SagaModePerformanceTest>();

            var allResults = new List<PerformanceTestResult>();

            try
            {
                // 运行AT模式性能测试
                Console.WriteLine("\n开始AT模式性能测试...");
                var atResults = await atModeTest.RunTestsAsync();
                allResults.AddRange(atResults);
                Console.WriteLine("AT模式性能测试完成");

                // 运行TCC模式性能测试
                Console.WriteLine("\n开始TCC模式性能测试...");
                var tccResults = await tccModeTest.RunTestsAsync();
                allResults.AddRange(tccResults);
                Console.WriteLine("TCC模式性能测试完成");

                // 运行SAGA模式性能测试
                Console.WriteLine("\n开始SAGA模式性能测试...");
                var sagaResults = await sagaModeTest.RunTestsAsync();
                allResults.AddRange(sagaResults);
                Console.WriteLine("SAGA模式性能测试完成");

                // 输出测试结果
                PrintTestResults(allResults);

                // 保存测试结果到文件
                await SaveTestResultsAsync(allResults);
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "性能测试执行过程中发生错误");
                throw;
            }
        }

        /// <summary>
        /// 打印测试结果
        /// </summary>
        /// <param name="results">测试结果列表</param>
        private static void PrintTestResults(List<PerformanceTestResult> results)
        {
            Console.WriteLine("\n性能测试结果:");
            Console.WriteLine("========================================");

            foreach (var result in results)
            {
                Console.WriteLine($"\n测试场景: {result.TestName}");
                Console.WriteLine($"总请求数: {result.TotalRequests}");
                Console.WriteLine($"成功请求数: {result.SuccessfulRequests}");
                Console.WriteLine($"失败请求数: {result.FailedRequests}");
                Console.WriteLine($"成功率: {result.SuccessRate:P2}");
                Console.WriteLine($"总耗时: {result.TotalTime / 1000.0:F2} 秒");
                Console.WriteLine($"平均响应时间: {result.AverageResponseTime:F2} 毫秒");
                Console.WriteLine($"最小响应时间: {result.MinResponseTime:F2} 毫秒");
                Console.WriteLine($"最大响应时间: {result.MaxResponseTime:F2} 毫秒");
                Console.WriteLine($"P50响应时间: {result.P50ResponseTime:F2} 毫秒");
                Console.WriteLine($"P95响应时间: {result.P95ResponseTime:F2} 毫秒");
                Console.WriteLine($"P99响应时间: {result.P99ResponseTime:F2} 毫秒");
                Console.WriteLine($"吞吐量: {result.Throughput:F2} 请求/秒");
                Console.WriteLine("----------------------------------------");
            }

            // 按模式分组统计
            var atResults = results.Where(r => r.TestName.Contains("AT模式")).ToList();
            var tccResults = results.Where(r => r.TestName.Contains("TCC模式")).ToList();
            var sagaResults = results.Where(r => r.TestName.Contains("SAGA模式")).ToList();

            Console.WriteLine("\n模式性能对比:");
            Console.WriteLine("========================================");
            Console.WriteLine($"AT模式平均吞吐量: {atResults.Average(r => r.Throughput):F2} 请求/秒");
            Console.WriteLine($"TCC模式平均吞吐量: {tccResults.Average(r => r.Throughput):F2} 请求/秒");
            Console.WriteLine($"SAGA模式平均吞吐量: {sagaResults.Average(r => r.Throughput):F2} 请求/秒");

            Console.WriteLine($"AT模式平均响应时间: {atResults.Average(r => r.AverageResponseTime):F2} 毫秒");
            Console.WriteLine($"TCC模式平均响应时间: {tccResults.Average(r => r.AverageResponseTime):F2} 毫秒");
            Console.WriteLine($"SAGA模式平均响应时间: {sagaResults.Average(r => r.AverageResponseTime):F2} 毫秒");
        }

        /// <summary>
        /// 保存测试结果到文件
        /// </summary>
        /// <param name="results">测试结果列表</param>
        private static async Task SaveTestResultsAsync(List<PerformanceTestResult> results)
        {
            var timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss");
            var fileName = $"PerformanceTestResults_{timestamp}.json";

            try
            {
                // 使用System.Text.Json序列化结果
                var json = System.Text.Json.JsonSerializer.Serialize(results, new System.Text.Json.JsonSerializerOptions
                {
                    WriteIndented = true
                });

                await File.WriteAllTextAsync(fileName, json);
                Console.WriteLine($"\n测试结果已保存到: {fileName}");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"保存测试结果失败: {ex.Message}");
            }
        }
    }
}